package com.zonhar.autofeed.cron;

import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.mail.MailUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pi4j.io.gpio.*;
import com.zonhar.autofeed.common.device.camera.CameraDevice;
import com.zonhar.autofeed.common.device.hcsr04.HcsrTask;
import com.zonhar.autofeed.common.device.hcsr04.RangeSensor;
import com.zonhar.autofeed.common.util.RedisUtil;
import com.zonhar.autofeed.entities.entity.DistConfigEntity;
import com.zonhar.autofeed.entities.entity.SensorEntity;
import com.zonhar.autofeed.service.DistConfigService;
import com.zonhar.autofeed.service.SensorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Objects;

@Component
public class Hcsr04Cron {

    private final static Logger log = LoggerFactory.getLogger(Hcsr04Cron.class);

    @Autowired
    private DistConfigService distConfigService;

    @Autowired
    private SensorService sensorService;

    @Autowired
    private HcsrTask hcsrTask;

    @Autowired
    private RedisUtil redisUtil;


    @Scheduled(cron="*/10 * * * * ?")
    public void  run(){
        Object hcsr04Key = redisUtil.get("HCSR-04-KEY");
        if(Objects.isNull(hcsr04Key)){
            synchronized (this){
                final GpioController gpio = GpioFactory.getInstance();
                GpioPinDigitalOutput sensorTrigger = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_24,
                        "Sensor Trigger", PinState.LOW);
                GpioPinDigitalInput sensorResult = gpio.provisionDigitalInputPin(RaspiPin.GPIO_03,
                        "Sensor Result",PinPullResistance.PULL_UP);
                //异步探测距离
                hcsrTask.csrRun(sensorTrigger,sensorResult);
                gpio.unprovisionPin(sensorTrigger);
                gpio.unprovisionPin(sensorResult);
                gpio.shutdown();
            }
        }else {
            log.info("暖暖在吃饭。。。");
        }

    }

   // @Async
    public void asyncHcSr(){
        if(getSensor()){
            DistConfigEntity distConfigEntity = getHcDistConfig("hcCron");
            if(Boolean.parseBoolean(distConfigEntity.getDistValue())){
                log.info("HC-SR04超声波传感器测距开始。。。");
                final GpioController gpio = GpioFactory.getInstance();
                GpioPinDigitalOutput sensorTrigger = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_24,
                        "Sensor Trigger", PinState.LOW);
                GpioPinDigitalInput sensorResult = gpio.provisionDigitalInputPin(RaspiPin.GPIO_03,
                        "Sensor Result",PinPullResistance.PULL_UP);
                try {
                    //创建超声波距离传感器
                    RangeSensor rangesensor = new RangeSensor(sensorTrigger, sensorResult);
                    // Get the range
                    double  distance = rangesensor.getRange();
                    System.out.println("超声波测距 =" + distance + "cm");
                    log.info("超声波测距 =" + distance + "cm");

                    //发送邮件
                    DistConfigEntity propHc = getHcDistConfig("propHc");
                    if(Boolean.parseBoolean(propHc.getDistValue())){
                        DistConfigEntity warnMax = getHcDistConfig("warnMax");
                        DistConfigEntity warnMin = getHcDistConfig("warnMin");
                        if(distance >= Double.parseDouble(warnMin.getDistValue()) && distance <= Double.parseDouble(warnMax.getDistValue())){
                            String fileName ="rp-" + DateUtil.format(new Date(), "yyyy-MM-dd") + System.currentTimeMillis() + ".png";
                            //捕抓图像
                            String url = CameraDevice.takeBufferedStill("/Users/zonhar/Desktop", fileName);
                            String tel = tel(url);
                            //推送消息
                            MailUtil.send(getSendEmail(),"猫粮自动投喂机通知",tel,true);
                            log.info("超声波测距传感器邮件推送成功");
                        }
                    }

                }finally {
                    gpio.unprovisionPin(sensorTrigger);
                    gpio.unprovisionPin(sensorResult);
                    log.info("HC-SR04超声波传感器测距结束。。。");
                }

            }else {
                log.info("HC-SR04超声波传感器调度已停止");
            }

        }else {
            log.warn("HC-SR04超声波传感器已停用");
        }
    }


    private DistConfigEntity getHcDistConfig(String field){
        QueryWrapper<DistConfigEntity> queryWrapper =new QueryWrapper<>();
        queryWrapper.eq("dist_group","hc_sr04");
        queryWrapper.eq("dist_name",field);
        return distConfigService.getOne(queryWrapper);
    }

    private boolean getSensor(){
        SensorEntity sensorEntity = sensorService.getById(4);
        return sensorEntity.getStat().equals(0);
    }

    /**
     * 获取收件人
     * @return
     */
    private String getSendEmail(){
        QueryWrapper<DistConfigEntity> queryWrapper =new QueryWrapper<>();
        queryWrapper.eq("dist_name","email");
        queryWrapper.eq("dist_group","params");
        DistConfigEntity configEntity = distConfigService.getOne(queryWrapper);
        return configEntity.getDistValue();
    }

    private static String tel(String url){
        String sb = "<div>" +
                "<h1>暖暖疑似正在进食</h1>" +
                "<img src='" + url + "' alt='未知错误' />" +
                "</div>";
        return sb;
    }

}
